package com.cc.app.ui;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.LinearInterpolator;

import com.cc.app.view.TestView;

import java.util.Random;

/**
 * progress
 */
public class ProgressView extends TestView {

    private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);

    private float width;
    private float height;
    private float cx = 300;

    private int gap;
    private float ratio;

    private float ratio2;

    private RectF rect;

    private int step;

    private ValueAnimator animator;

    private ValueAnimator rotateAnimator;

    private int progress;

    private int leafSize;

    public ProgressView(Context context) {
        this(context, null);
    }

    public ProgressView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        initPaint();
        initAnimator();

        width = 600;
        height = 120;
        gap = 15;
        rect = new RectF(-width / 2 + gap, -height / 2 + gap, -width / 2 + gap, height / 2 - gap);
    }

    private void initPaint() {
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.GREEN);
        paint.setStyle(Paint.Style.FILL);
        paint.setStrokeCap(Paint.Cap.ROUND);
        paint.setStrokeJoin(Paint.Join.BEVEL);
    }

    private void initAnimator() {
        animator = ValueAnimator.ofFloat(0, 1).setDuration(2000);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                ratio = animation.getAnimatedFraction();

                if (step == 0) {
                    progress = (int) (100 * ratio);
                    rect.right = -width / 2 + gap + width * (test ? ratio : progress / 100f);
                }

                invalidate();
            }
        });

        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                if (step == 0 && test && ratio == 1) {
                    step++;
                }

                if (step == 1) {
                    animator.start();
                    step++;
                }
            }
        });

        rotateAnimator = ValueAnimator.ofFloat(0, 1).setDuration(1000);
        rotateAnimator.setInterpolator(new LinearInterpolator());
        rotateAnimator.setRepeatCount(ValueAnimator.INFINITE);

        rotateAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                ratio2 = animation.getAnimatedFraction();
                invalidate();
            }
        });

        rotateAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                invalidate();
            }
        });
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        canvas.drawColor(Color.argb(255, 255, 205, 80));

        canvas.save();
        canvas.translate(getWidth() / 2, getHeight() / 2);
        paint(canvas);
        canvas.restore();
    }

    private void paint(Canvas canvas) {
        paint.setColor(Color.argb(255, 250, 230, 155));
        paint.setStyle(Paint.Style.FILL);

        int radius = 800;
        RectF back = new RectF(-width / 2, -height / 2, width / 2, height / 2);
        canvas.drawRoundRect(back, radius, radius, paint);

        Path path = new Path();
        path.addRoundRect(rect, radius, radius, Path.Direction.CW);

        canvas.save();
        canvas.clipPath(path);
        paint.setColor(Color.argb(250, 255, 168, 0));
        canvas.drawRect(new RectF(rect.left, rect.top, rect.right - 100, rect.bottom), paint);

//        paint.setTextSize(70);
//        String text = progress + "%";
//        Paint.FontMetrics fontMetrics = paint.getFontMetrics();
//        float top = fontMetrics.top;
//        float bottom = fontMetrics.bottom;
//        paint.setTextAlign(Paint.Align.CENTER);
//        paint.setColor(Color.WHITE);
//        canvas.drawText(text, 0, (rect.bottom + rect.top - top - bottom) / 2, paint);
        canvas.restore();

        paintCircle(canvas);

        drawLeafs(canvas);
    }

    private void paintCircle(Canvas canvas) {
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(Color.rgb(255, 205, 80));

        float halfHeight = height / 2;
        canvas.drawCircle(cx - halfHeight, 0, halfHeight - 10, paint);

        paint.setColor(Color.WHITE);
        if (progress < 100) {
            canvas.drawCircle(cx - halfHeight, 0, 5, paint);
        }

        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(10);

        canvas.drawCircle(cx - halfHeight, 0, halfHeight - 10, paint);

        paintLeaf(canvas);
    }

    private void paintLeaf(Canvas canvas) {
        canvas.save();

        float halfHeight = height / 2;
        canvas.translate(cx - halfHeight, 0);

        paint.setColor(Color.WHITE);
        paint.setStrokeWidth(1);

        if (progress < 100) {
            paint.setStyle(Paint.Style.FILL);

            canvas.rotate(-360 * ratio2, 0, 0);

            Path path = new Path();
            path.moveTo(0, 0);
            path.cubicTo(-halfHeight, -halfHeight, halfHeight, -halfHeight, 0, 0);
            path.close();
            canvas.drawPath(path, paint);

            for (int i = 0; i < 3; i++) {
                canvas.rotate(90);
                Path path2 = new Path();
                path2.moveTo(0, 0);
                path2.cubicTo(-halfHeight, -halfHeight, halfHeight, -halfHeight, 0, 0);
                path2.close();
                canvas.drawPath(path2, paint);
            }

            drawLeafs(canvas);

        } else {
            paint.setStyle(Paint.Style.FILL);
            paint.setTextAlign(Paint.Align.LEFT);

            String text = "100%";
            paint.setTextSize(Math.min(ratio * 4 * 30, 30));
            Paint.FontMetrics fontMetrics = paint.getFontMetrics();
            float top = fontMetrics.top;
            float bottom = fontMetrics.bottom;
            float width = paint.measureText(text);

            canvas.drawText(text, -width / 2, -top / 2 - bottom / 2, paint);
        }
        canvas.restore();
    }

    private void drawLeafs(Canvas canvas) {
        paint.setColor(Color.GREEN);
        for (int i = 0; i < leafSize; i++) {
            canvas.save();
            RectF rect = new RectF(-10, -10, -10, -10);

            rect.offset(-cx * ratio, 100 * ratio);
            int angle = (int) ((random.nextBoolean() ? 1 : -1) * (360 * random.nextFloat()));
            canvas.rotate(angle, rect.centerX(), rect.centerY());

            canvas.drawRect(rect, paint);
            canvas.restore();
        }
    }

    public void setProgress(int progress) {
        if (progress < 0)
            progress = 0;

        if (progress > 100)
            progress = 100;

        this.progress = progress;

        if (this.progress == 100) {
            rotateAnimator.end();
        } else {
            step = 0;
            rotateAnimator.start();
        }

        animator.start();
    }

    public void addProgress(int progress) {
        if (progress <= 0 || progress > 100)
            return;


        leafSize = progress / 5;
        setProgress(this.progress + progress);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getY() < 100) {
            test = !test;
        }

        if (event.getY() < 800) {
            setProgress(0);
        } else
            addProgress(10);

        return super.onTouchEvent(event);
    }


}
